export interface IWSSocket {
	init: () => void
	connect: (url: string, token: string) => void
	reconnect: (wsurl: string, accessToken: string) => void
	close: () => void
	sendMessage: (agentData: string | ArrayBuffer) => void
	onConnect: (callback: any) => void
	onMessage: (callback: any) => void
	onClose: (callback: any) => void
}

export const defaultWsUrl = process.env.WS_URL || 'ws://127.0.0.1:7778/im'

let wsurl = ""
let accessToken = ""
let messageCallBack = null as any
let closeCallBack = null as any
let connectCallBack = null as any
let isConnect = false //连接标识 避免重复连接
let rec: NodeJS.Timeout = null as any
let isInit = false

const init = () => {
	// 防止重复初始化
	if (isInit) {
		return
	}
	isInit = true
	uni.onSocketOpen((res) => {
		console.log("WebSocket连接已打开")
		isConnect = true
		// 发送登录命令
		const loginInfo = {
			cmd: 0,
			data: {
				accessToken: accessToken
			}
		}
		uni.sendSocketMessage({
			data: JSON.stringify(loginInfo)
		})
	})
	uni.onSocketMessage((res) => {
		const sendInfo = JSON.parse(res.data)
		if (sendInfo.cmd == 0) {
			heartCheck.start()
			connectCallBack && connectCallBack()
			console.log('WebSocket登录成功')
		} else if (sendInfo.cmd == 1) {
			// 重新开启心跳定时
			heartCheck.reset()
		} else {
			// 其他消息转发出去
			console.log("接收到消息", sendInfo)
			messageCallBack && messageCallBack(sendInfo.cmd, sendInfo.data)
		}
	})
	uni.onSocketClose((res) => {
		console.log('WebSocket连接关闭')
		isConnect = false //断开后修改标识
		closeCallBack && closeCallBack(res)
	})
	uni.onSocketError((e) => {
		console.log(e)
		isConnect = false //连接断开修改标识
		uni.showModal({
			content: '连接失败，可能是websocket服务不可用，请稍后再试',
			showCancel: false,
		})
	})
}

const connect = (url: string, token: string) => {
	wsurl = url
	accessToken = token
	if (isConnect) {
		return
	}
	uni.connectSocket({
		url: wsurl,
		success: (res) => {
			console.log("websocket连接成功")
		},
		fail: (e) => {
			console.log(e)
			console.log("websocket连接失败，10s后重连")
			setTimeout(() => {
				wsApi.connect(url, token)
			}, 10000)
		}
	})
}

const reconnect = (wsurl: string, accessToken: string) => {
	console.log("尝试重新连接")
	if (isConnect) {
		//如果已经连上就不在重连了
		return
	}
	rec && clearTimeout(rec)
	rec = setTimeout(function () { // 延迟15秒重连  避免过多次过频繁请求重连
		wsApi.connect(wsurl, accessToken)
	}, 15000)
}

//心跳设置
const heartCheck = {
	timeout: 10000, //每段时间发送一次心跳包 这里设置为30s
	timeoutObj: null, //延时发送消息对象（启动心跳新建这个对象，收到消息后重置对象）
	start: function () {
		if (isConnect) {
			console.log('发送WebSocket心跳')
			const heartBeat = {
				cmd: 1,
				data: {}
			}
			uni.sendSocketMessage({
				data: JSON.stringify(heartBeat),
				fail(res) {
					console.log(res)
				}
			})
		}
	},
	reset: function () {
		clearTimeout(this.timeoutObj)
		this.timeoutObj = setTimeout(function () {
			heartCheck.start()
		}, this.timeout)
	}
}

const close = () => {
	if (!isConnect) {
		return
	}
	uni.closeSocket({
		code: 3000,
		complete: (res) => {
			console.log("关闭websocket连接")
			isConnect = false
		},
		fail: (e) => {
			console.log("关闭websocket连接失败", e)
		}
	})
}

// 实际调用的方法
const sendMessage = (agentData: string | ArrayBuffer) => {
	uni.sendSocketMessage({
		data: agentData
	})
}

const onConnect = (callback) => {
	return connectCallBack = callback
}

const onMessage = (callback) => {
	return messageCallBack = callback
}

const onClose = (callback) => {
	return closeCallBack = callback
}

const wsApi: IWSSocket = {
	init,
	connect,
	reconnect,
	close,
	sendMessage,
	onConnect,
	onMessage,
	onClose,
}

export default wsApi